//
//  MapController.m
//  Belt
//
//  Created by nsm on 2017/12/21.
//  Copyright © 2017年 beisheng. All rights reserved.
//

#import "MapController.h"
#import "AMapHelper.h"
#import "MapCell.h"
#import <IQKeyboardManager.h>

@interface CenterView : UIImageView
@property (nonatomic, strong) UIView *loadingView;
- (void)startAnimating;
- (void)stopAnimating;
@end

@implementation CenterView
- (instancetype)init {
    self = [super init];
    if (self) {
        self.layer.anchorPoint = CGPointMake(0.5, 1);
        self.image = NameImage(@"home_center");
        [self sizeToFit];
        
        _loadingView = [UIView new];
        _loadingView.size = CGSizeMake(self.width, self.width);
        [self addSubview:_loadingView];
    }
    return self;
}

- (void)startAnimating {
    self.loadingView.isLoading = YES;
}

- (void)stopAnimating {
    self.loadingView.isLoading = NO;
}

@end

@interface MapController ()  <MKMapViewDelegate, UISearchBarDelegate, AMapSearchDelegate>
@property (nonatomic, strong) CenterView *centerView;
@property (nonatomic, strong) UIButton *gpsBtn;
@property (nonatomic, strong) MKMapView *mapView;
@property (nonatomic, strong) AMapSearchAPI *searchAPI;
@property (nonatomic, strong) CityModel *city;
@property (nonatomic) NSUInteger searchPage;
@property (nonatomic, copy) NSString *searchString;
@property (nonatomic, strong) UIView *userLocationView;
@property (nonatomic) CLLocationCoordinate2D location;
@end

@implementation MapController {
    UISearchBar *_searchBar;
    UIView      *_maskView;
    UIView      *_searchView;
    CGFloat     _topHeight;
    NSMutableArray <MKPointAnnotation *> *_annotations;
}

#pragma mark - lifeCycle
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    if ([self locationServicesEnabled]) {
        [_amapLocationManager startUpdatingLocation];
    }
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    
    self.centerView.center = CGPointMake(_mapView.width/2, _mapView.height/2);
    self.gpsBtn.hidden = NO;
    
    CLLocationCoordinate2D coordinate = self.mapView.userLocation.coordinate;
    self.location = coordinate;
    if (coordinate.latitude == 0 || coordinate.longitude == 0) return;
    MKCoordinateRegion region = MKCoordinateRegionMake(coordinate, MKCoordinateSpanMake(0.1, 0.1));
    [self.mapView setRegion:region animated:YES];
}

- (BOOL)locationServicesEnabled {
    /**
     授权状态为枚举值
     kCLAuthorizationStatusNotDetermined //用户尚未对该应用程序作出选择
     kCLAuthorizationStatusRestricted //应用程序的定位权限被限制
     kCLAuthorizationStatusAuthorizedAlways //一直允许获取定位
     kCLAuthorizationStatusAuthorizedWhenInUse //在使用时允许获取定位
     kCLAuthorizationStatusAuthorized //已废弃，相当于一直允许获取定位
     kCLAuthorizationStatusDenied //拒绝获取定位
     */
    BOOL enabled = NO;
    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
    if ([CLLocationManager locationServicesEnabled] &&
        (status == kCLAuthorizationStatusNotDetermined ||
         status == kCLAuthorizationStatusAuthorizedAlways ||
         status == kCLAuthorizationStatusAuthorizedWhenInUse)) {
            enabled = YES;
        }
    else if (status == kCLAuthorizationStatusDenied) {
        NSString *title = FormatString(@"打开[定位服务]来允许[%@]确定您的位置", kAppBundleName);
        NSString *desc = @"请在系统设置中开启定位服务(设置>隐私>定位服务>开启)";
        [self showAlert:title message:desc cancel:nil done:^(UIAlertAction *action) {
            OpenURL(UIApplicationOpenSettingsURLString);
        }];
    }
    return enabled;
}

#pragma mark - override
- (void)didInitialize {
    [super didInitialize];
    
    self.ignoreViewDidLayoutSubviews = YES;
}

#pragma mark - initialization
- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self initMapView];
    [self initSearchView];
}

- (void)initMapView {
    _mapView = [MKMapView new];
    _mapView.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight-kNavBarHeight);
    _mapView.delegate = self;
    _mapView.showsUserLocation = YES;
    [self.view addSubview:_mapView];
    
    if (@available(iOS 9.0, *)) {
        _mapView.showsCompass = YES;
    }
    
    UIButton *gpsBtn = [UIButton new];
    gpsBtn.backgroundColor = [UIColor whiteColor];
    gpsBtn.size = CGSizeMake(40, 40);
    gpsBtn.left = 15;
    [gpsBtn setImage:BundleImage(@"nsm_gps_n") forState:UIControlStateNormal];
    [gpsBtn setImage:BundleImage(@"nsm_gps_s") forState:UIControlStateSelected];
    [gpsBtn addTarget:self action:@selector(gpsAction) forControlEvents:UIControlEventTouchUpInside];
    [_mapView addSubview:gpsBtn];
    _gpsBtn = gpsBtn;
    _gpsBtn.hidden = YES;
}

- (void)initSearchView {
    _maskView = [UIView new];
    _maskView.backgroundColor = WhiteColor(0, 0.3);
    _maskView.size = CGSizeMake(kScreenWidth, kScreenHeight-kNavBarHeight);
    
    @nsm_weak(self)
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithActionBlock:^(id  _Nonnull sender) {
        @nsm_strong(self)
        [self hideSearchView];
    }];
    [_maskView addGestureRecognizer:tap];
    
    _searchView = [UIView new];
    _searchView.backgroundColor = COLOR_5;
    _searchView.size = CGSizeMake(kScreenWidth, kScreenHeight-kNavBarHeight-84-kSafeAreaBottom);
    [self.view addSubview:_searchView];
    
    _searchView.layer.shadowColor = COLOR_1.CGColor;
    _searchView.layer.shadowOpacity = 0.8;
    _searchView.layer.shadowRadius = 3;
    _searchView.layer.shadowOffset = CGSizeZero;
    
    UIView *topView = [UIView new];
    topView.backgroundColor = COLOR_4;
    topView.size = _searchView.size;
    [_searchView addSubview:topView];
    ViewCorner(topView, 10);
    
    _searchBar = [UISearchBar new];
    _searchBar.width = kScreenWidth-7*2;
    _searchBar.delegate = self;
    _searchBar.tintColor = THEME_COLOR;
    _searchBar.placeholder = @"搜索附近";
    _searchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
    // 修改背景和黑线 (barTintColor只能去背景)
    _searchBar.backgroundImage = [UIImage imageWithColor:COLOR_4];
    // 修改字体颜色
    UITextField *searchField = [_searchBar valueForKey:@"_searchField"];
    searchField.clearButtonMode = UITextFieldViewModeWhileEditing;
    searchField.font = CustomFont(15);
    searchField.backgroundColor = GROUP_TABLECOLOR;
    
    [_searchBar sizeToFit];
    _searchBar.top = 10;
    _searchBar.centerX = kScreenWidth/2;
    [_searchView addSubview:_searchBar];
    
    // 手势标记
    UIView *tipView = [UIView new];
    tipView.backgroundColor = SELECTED_COLOR;
    tipView.size = CGSizeMake(44, 6);
    tipView.center = CGPointMake(kScreenWidth/2, 10);
    [_searchView addSubview:tipView];
    ViewCorner(tipView, 3);
    
    // 分割线
    UIView *line = [UIView new];
    line.backgroundColor = SEPARATOR_COLOR;
    line.size = CGSizeMake(kScreenWidth, kSinglePixel*2);
    line.top = _searchBar.bottom+4;
    [_searchView addSubview:line];
    
    _topHeight = line.top;
    _searchView.top = kScreenHeight-kNavBarHeight - kSafeAreaBottom - _topHeight;
    
    _gpsBtn.bottom = _searchView.top - 20;

    // 列表
    [self.tableView removeFromSuperview];
    [_searchView addSubview:self.tableView];
    
    self.tableView.backgroundColor = COLOR_4;
    self.tableView.top = line.bottom;
    self.tableView.width = kScreenWidth;
    self.tableView.height = _searchView.height - line.bottom;
    self.tableView.estimatedRowHeight = 64;
    self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
    
    self.tableView.sourceManager.classForCellAtIndexPath = ^Class(NSIndexPath *indexPath) {
        return [MapCell class];
    };
    
    MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
        @nsm_strong(self)
        self.searchPage += 1;
        [self searchPOI:self.searchString];
    }];
    [footer setTitle:@"" forState:MJRefreshStateIdle];
    [footer setTitle:@"已经全部加载完毕" forState:MJRefreshStateNoMoreData];
    footer.stateLabel.font = CustomFont(13);
    footer.stateLabel.textColor = SUB_TEXT_COLOR;
    footer.refreshingTitleHidden = YES;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    footer.automaticallyHidden = YES;
#pragma clang diagnostic pop
    self.tableView.mj_footer = footer;
}

#pragma mark - setter/getter
- (AMapSearchAPI *)searchAPI {
    if (!_searchAPI) {
        _searchAPI = [AMapSearchAPI new];
        _searchAPI.delegate = self;
    }
    return _searchAPI;
}

#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
    AMapPOI *poi = tableView.sourceManager.dataArray[indexPath.row];
    !self.didSelectPOI?:self.didSelectPOI(poi);
    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark - MKMapViewDelegate
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(nonnull MKUserLocation *)userLocation {
    CLLocationCoordinate2D coordinate = userLocation.coordinate;
    if (coordinate.latitude == 0 || coordinate.longitude == 0) return;
    
    _amapHelper.userCoordinate = coordinate;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        MKCoordinateRegion region = MKCoordinateRegionMake(coordinate, MKCoordinateSpanMake(0.1, 0.1));
        [self.mapView setRegion:region animated:YES];
        
        self.centerView.center = CGPointMake(mapView.width/2, mapView.height/2);
    });
    self.gpsBtn.hidden = NO;
}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
    if ([annotation isKindOfClass:[MKPointAnnotation class]]) {
        static NSString *ID = @"annotation_id";
        MKAnnotationView *view = [mapView dequeueReusableAnnotationViewWithIdentifier:ID];
        if (!view)
            view = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:ID];
        view.image = NameImage(@"home_annotation");
        view.annotation = annotation;
        // view.layer.zPosition = -1;
        return view;
    } else if ([annotation isKindOfClass:[MKUserLocation class]]) {
        static NSString *ID = @"annotation_user";
        MKAnnotationView *view = [[NSClassFromString(@"MKModernUserLocationView") alloc] initWithAnnotation:annotation reuseIdentifier:ID];
        // view.layer.zPosition = 100;
        return view;
    }
    return nil;
}

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
    id <MKAnnotation> annotation = view.annotation;
    // 关掉弹出
    [mapView deselectAnnotation:annotation animated:YES];
    if ([annotation isKindOfClass:[MKUserLocation class]]) return;
    
    NSDictionary *item = [(MKPointAnnotation *)annotation constDic];
}

- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
    self.gpsBtn.selected = NO;
}

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
     [self refreshCenter];
}

#pragma mark - UISearchBarDelegate
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
    searchBar.showsCancelButton = YES;
    [self showSearchView];
    
    if (!self.tableView.sourceManager.dataArray.count && !searchBar.text.length) {
        [self searchBar:searchBar textDidChange:searchBar.text];
    }
}

- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
    searchBar.showsCancelButton = NO;
}

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    [searchBar resignFirstResponder];
    [self hideSearchView];
}

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    [searchBar resignFirstResponder];
}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
    _searchPage = 1;
    _searchString = searchText;
    [self searchPOI:searchText];
}

#pragma mark - AMapSearchDelegate
- (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response {
    [self.tableView.mj_footer endRefreshing];
    [self.centerView stopAnimating];
    if (_searchPage > 1)
        [self.tableView.sourceManager.dataArray addObjectsFromArray:response.pois];
    else
        self.tableView.sourceManager.dataArray = (response.pois).mutableCopy;
    [self.tableView reloadData];
}

- (void)AMapSearchRequest:(id)request didFailWithError:(NSError *)error {
    [self.tableView.mj_footer endRefreshing];
    [self.centerView stopAnimating];
}

#pragma mark - network
- (void)addAnnotations:(NSArray *)data {
    [_mapView removeAnnotations:_annotations];
    
    _annotations = [NSMutableArray new];
    for (NSDictionary *dic in data) {
        MKPointAnnotation *ann = [MKPointAnnotation new];
        ann.coordinate = CLLocationCoordinate2DMake([dic[@"lat"] doubleValue],
                                                    [dic[@"lng"] doubleValue]);
        ann.constDic = dic;
        [_annotations addObject:ann];
    }
    [_mapView addAnnotations:_annotations];
    
    if (!self.mapView.isUserLocationVisible) {
        @nsm_weak(self)
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            @nsm_strong(self)
            [self zoomToFitMapAnnotations:self->_mapView];
        });
    }
}

- (void)zoomToFitMapAnnotations:(MKMapView*)mapView {
    if (!mapView.annotations.count) return;
    
    CLLocationCoordinate2D topLeftCoord;
    topLeftCoord.latitude = -90;
    topLeftCoord.longitude = 180;
    
    CLLocationCoordinate2D bottomRightCoord;
    bottomRightCoord.latitude = 90;
    bottomRightCoord.longitude = -180;
    
    for (MKPointAnnotation *annotation in mapView.annotations) {
        topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
        topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);
        bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
        bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
    }
    
    MKCoordinateRegion region;
    region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) *0.5;
    region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) *0.5;
    // 四周留白
    region.span.latitudeDelta =fabs(topLeftCoord.latitude - bottomRightCoord.latitude) *1.15;
    region.span.longitudeDelta =fabs(bottomRightCoord.longitude - topLeftCoord.longitude) *1.15;
    
    region = [mapView regionThatFits:region];
    [mapView setRegion:region animated:YES];
}

#pragma mark - method/public

#pragma mark - 中间搜索
- (CenterView *)centerView {
    if (!_centerView) {
        _centerView = [CenterView new];
        // _centerView.center = CGPointMake(_mapView.width/2, _mapView.height/2);
        [_mapView addSubview:_centerView];
    }
    return _centerView;
}

- (void)refreshCenter {
    [self.centerView startAnimating];
    
    if ([self locationServicesEnabled]) {
        CGPoint point = CGPointMake(self.mapView.width/2, self.mapView.height/2);
        CLLocationCoordinate2D location = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
        self.location = location;
        _searchPage = 1;
        _searchString = @"";
        [self searchPOI:@""];
    } else
        [self.centerView stopAnimating];
}

#pragma mark - method/private
- (void)showSearchView {
    if (_maskView.superview) [_maskView removeFromSuperview];
    [self.view insertSubview:_maskView belowSubview:_searchView];
    
    [_searchBar becomeFirstResponder];
    [UIView animateWithDuration:0.25 animations:^{
        self->_searchView.top = 84;
    }];
}

- (void)hideSearchView {
    if (_maskView.superview) [_maskView removeFromSuperview];
    
    [_searchBar resignFirstResponder];
    // 恢复左右navItem
    self.navigationItem.leftBarButtonItem.enabled = YES;
    for (UIBarButtonItem *item in self.navigationItem.rightBarButtonItems) {
        item.enabled = YES;
    }
    [UIView animateWithDuration:0.25 animations:^{
        self->_searchView.top = kScreenHeight-kNavBarHeight - kSafeAreaBottom - self->_topHeight;
    }];
}

- (void)searchPOI:(NSString *)text {
    AMapPOIAroundSearchRequest *request = [AMapPOIAroundSearchRequest new];
    request.keywords = text;
    request.radius = 10000;
    request.page = self.searchPage;
    request.location = [AMapGeoPoint locationWithLatitude:self.location.latitude
                                                longitude:self.location.longitude];
    [self.searchAPI AMapPOIAroundSearch:request];
}

#pragma mark - action
- (void)gpsAction {
    MKCoordinateRegion region = MKCoordinateRegionMake(self.mapView.userLocation.coordinate, MKCoordinateSpanMake(0.1, 0.1));
    [self.mapView setRegion:region animated:YES];
    // [self.mapView setCenterCoordinate:self.mapView.userLocation.coordinate animated:YES];
    self.gpsBtn.selected = YES;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

@end
